from django.contrib.auth.models import User as AuthUser
from myhomework.models import *
from myhomework.exceptions.exception import *
from django.contrib.auth.models import Permission
from myhomework.utils import get_param
from django.http import HttpResponse
from django.utils.decorators import available_attrs
from myhomework.common.daos import *

try:
    from functools import update_wrapper, wraps
except ImportError:
    from django.utils.functional import update_wrapper, wraps  # Python 2.4 fallback.
    


class PermissionDao(object):
    
    @staticmethod
    def user_add_perm(user,perm):
        permission = Permission.objects.filter(codename=perm)
        if(not permission):
            permission = Permission(name=perm,codename=perm,content_type_id=1)
            permission.save()
        else:
            permission=permission.get()
        user.user_permissions.add(permission)
        user.save()
        
    
    @staticmethod
    def user_add_perms(user,perms):
        for perm in perms:
            PermissionDao.user_add_perm(user, perm)
    
    @staticmethod
    def user_has_perm(user,perm):
        if(not user.is_active):
            return False
        
        if(user.is_superuser):
            return True
        
        if(not perm or perm==''):
            return True
        
        if(perm in [permission.codename for permission in user.user_permissions.all()]):
            return True
        return False
    
    @staticmethod
    def user_has_perms(user,perms):
        for perm in perms:
            if(PermissionDao.user_has_perm(user, perm)):
                return True
        return False
    
    @staticmethod
    def user_remove_perm(user,perm):
        print perm
        permission = Permission.objects.filter(codename=perm)
        print 'ok9!!!!!!!!!!!!'
        if(not permission):
            return
        permission = permission.get()
        print 'ok10!!!!!!!!!!!!!!!!!'
        user.user_permissions.remove(permission)
        print 'ok11!!!!!!!!!!!'
        user.save()
    
    @staticmethod
    def user_remove_perms(user,perms):
        for perm in perms:
            PermissionDao.user_remove_perm(user, perm)
        print 'ok8!!!'
    
    @staticmethod
    def user_get_all_perms(user):
        if(not user):
            return []
        return [perm.codename for perm in user.user_permissions.all()]
    
    

  
#def require_perm(perm=''):
#    return user_passes_test(perm)
   




class UserDao(object):
    
    @staticmethod
    def add_user(user):    
        if ( AuthUser.objects.filter(username=user.student_id) ):
            raise UserIDExisted(user.student_id)
        
        auth_user = AuthUser.objects.create_user(username=user.student_id, email=user.email, password=user.password)
        auth_user.is_active=False
        auth_user.save()     
        user.auth_user = auth_user
        user.password = ''
        user.save()
    
    @staticmethod
    def edit_user(user):
        if (not User.objects.filter(student_id=user.student_id)):
            raise UserIDNotExisted(user.student_id)
         
        user.save()
            
    @staticmethod
    def delete_user(student_id):
        
        """
        user = UserDao.get_user_by_student_id(student_id)
        user.auth_user.delete()
        user.delete()
        user.auth_user.save()
        user.save()
        """
        
        user = UserDao.get_user_by_student_id(student_id)
        user.auth_user.is_active = False
        
        user.auth_user.save()
        user.save()
        
    @staticmethod
    def get_user_by_student_id(student_id):
        all_user = User.objects.filter(student_id=student_id)
        
        if (not all_user):
            raise UserIDNotExisted(student_id)
        
        return all_user.get()
    
    @staticmethod
    def is_user_in_a_group(student_id):
        user = UserDao.get_user_by_student_id(student_id)
        
        if ( user.group is None ):
            return False
        else:
            return True
        
    @staticmethod
    def  user_set_password(student_id, old_password, new_password1, new_password2):
        
        user = UserDao.get_user_by_student_id(student_id)
        
        if ( not user.auth_user.check_password(old_password) ):
            raise WrongPassword(student_id)
        
        if ( not new_password1 == new_password2 ):
            raise DifferentPassword(student_id)
        
        user.auth_user.set_password(new_password1)
        
        user.auth_user.save()     
        user.save()  
    
    @staticmethod
    def pass_user(student_id):
        
        user = UserDao.get_user_by_student_id(student_id)
        user.auth_user.is_active = True
        
        user.auth_user.save()
        user.save()
        
    @staticmethod
    def get_number_of_active_user():
        
        acitve_user_list = User.objects.filter(auth_user__is_active=True)
        
        count = acitve_user_list.all().count() 
        return count
    
    @staticmethod
    def get_number_of_not_active_user():
        
        acitve_user_list = User.objects.filter(auth_user__is_active=False)
        
        count = acitve_user_list.all().count() 
        return count
    
    @staticmethod
    def get_number_of_user():
        
        count = User.objects.all().count() 
        return count
    
    @staticmethod
    def get_user_list(start, limit):
        
        if ( start < 0 or start >= User.objects.all().count() ):
            start = 0
        if ( limit < 0 or start >= User.objects.all().count() ):
            limit = SettingDao.get_setting('user_number_per_page')
        
        output_user_list = User.objects.all()[start:start+limit]
                                              
        return output_user_list
                   
    
    @staticmethod
    def get_active_user_list(start, limit):

        acitve_user_list = User.objects.filter(auth_user__is_active=True)
        
        if ( start < 0 or start >= acitve_user_list.all().count() ):
            start = 0
        if ( limit < 0 ):
            limit = SettingDao.get_setting('user_number_per_page')
        
        if ( not acitve_user_list is None):
            output_user_list = acitve_user_list[start:start+limit]
 
        return output_user_list
    
    @staticmethod
    def get_not_active_user_list(start, limit):
                   
        not_acitve_user_list = User.objects.filter(auth_user__is_active=False)
        
        if ( start < 0 or start >= not_acitve_user_list.all().count() ):
            start = 0
        if ( limit < 0 ):
            limit = SettingDao.get_setting('user_number_per_page')
        
        
        if ( not not_acitve_user_list is None):
            output_user_list = not_acitve_user_list[start:start+limit]
 
        return output_user_list
    
    @staticmethod
    def set_user_TA(user_id):
        
        user = UserDao.get_user_by_student_id(user_id)
        
        permis_TA = 'TA'
        PermissionDao.user_add_perm( user.auth_user, permis_TA )
        
        user.auth_user.is_staff = True
        user.save()
    
    @staticmethod
    def remove_user_TA(user_id):
        
        user = UserDao.get_user_by_student_id(user_id)
        
        permis_TA = 'TA'
        PermissionDao.user_remove_perm( user.auth_user, permis_TA )
        
        user.auth_user.is_staff = False
        user.save()

"""
UserDao.set_user_TA('001')

user_list = UserDao.get_not_active_user_list(100, -1)
for user in user_list:
    print user
"""

"""
count = UserDao.get_number_of_user()
print count

output_user_list = UserDao.get_active_user_list('0','100')

if ( not output_user_list is None):
    for auser in output_user_list:
        print auser
else:
    print 'None'

"""


"""
new_user = User(student_id='001', password='001', email='a1@b.com')
UserDao.add_user(new_user)

new_user = User(student_id='002', email='a2@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='003', email='a3@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='004', email='a1@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='005', email='a5@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='006', email='a6@b.com')
UserDao.add_user(new_user)
"""
"""
new_user = User(student_id='007', email='a7@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='008', email='a8@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='009', email='a9@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='010', email='a10@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='011', email='a11@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='012', email='a12@b.com')
UserDao.add_user(new_user)
"""
"""
new_user = User(student_id='013', email='a13@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='014', email='a14@b.com')
UserDao.add_user(new_user)

new_user = User(student_id='015', email='a15@b.com')
UserDao.add_user(new_user)

new_user = User(student_id='016', email='a16@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='017', email='a17@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='018', email='a18@b.com')
UserDao.add_user(new_user)
"""



#UserDao.user_set_password('001', '111', '222', '222')

"""
old_user = User.objects.get(student_id='010')
old_user.email='vvv@bb.com'
UserDao.edit_user(old_user)
new_user = User.objects.get(student_id='010')
print new_user.email


find_user = UserDao.search_user_by_student_id('006')
print find_user
#print find_user.email
"""
"""
new_user = User(student_id='010',name="zyy",email='010@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='011', name="lch",email='011@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='012',name="czb", email='012@b.com')
UserDao.add_user(new_user)
new_user = User(student_id='013',name="yz", email='013@b.com')
UserDao.add_user(new_user)
"""



class GroupDao(object):
    
    """test"""
    @staticmethod
    def create_group(group, group_admin_id):
        print 'ok1002!!!!!!!!'
        group_admin = UserDao.get_user_by_student_id(group_admin_id)        
        
        #if ( not User.objects.filter(student_id=group_admin.student_id) ):
        #    raise UserIDNotExisted(group_admin.student_id)
        
        if ( Group.objects.filter(name = group.name) ):
            raise GroupNameDuplication(group.name)
        
        if ( not group_admin.group is None ):
            raise UserJoinGroupDuplication(group_admin.student_id)
        print 'ok1003!!!!!!!!'
        """modify"""
        #group = Group(administrator=group_admin, name=group_name)
        print 'ok101!!!!!!!!'
        permis_admin = '.'.join([str(group.id),'admin'])
        permis_member = '.'.join([str(group.id),'member'])
        PermissionDao.user_add_perms( group_admin.auth_user, [permis_admin, permis_member] )
        """modify"""
        print 'ok100!!!!!!!!'
        group.administrator = group_admin
        group.save()
        
        group_admin.group = group
        group_admin.save()
    
    """test"""
    @staticmethod
    def delete_group(group_id):
        
        group = GroupDao.get_group_by_id(group_id)
        
        all_user = group.users.all()
    
        """modify"""
        permis_admin = '.'.join([str(group.id), 'admin'])
        permis_member = '.'.join([str(group.id), 'member'])
        """modify"""
        
        for a_user in all_user:
            
            """modify"""
            if ( group.administrator.student_id == a_user.student_id ):
                PermissionDao.user_remove_perms(a_user.auth_user, [permis_admin, permis_member])  
            else:
                PermissionDao.user_remove_perm(a_user.auth_user, permis_member)
            """modify"""
            
            a_user.group = None
            a_user.save()
        
        group.delete()
        
    """test"""
    @staticmethod
    def edit_group_name(group_id, name):
        
        group = GroupDao.get_group_by_id(group_id) 
        
        if ( Group.objects.filter(name = name) ):
            raise GroupNameDuplication(group.name)
        
        """modify"""
        permis_admin = '.'.join([str(group.id), 'admin'])
        permis_member = '.'.join([str(group.id), 'member'])
        
        permis_admin_new = '.'.join([str(group.id), 'admin'])
        permis_member_new = '.'.join([str(group.id), 'member'])
        
        all_user = group.users.all()
        
        for a_user in all_user:
              
            if ( group.administrator.student_id == a_user.student_id ):
                PermissionDao.user_remove_perms( a_user.auth_user, [permis_admin, permis_member])  
                PermissionDao.user_add_perms( a_user.auth_user, [permis_admin_new, permis_member_new])
            else:
                PermissionDao.user_remove_perm(a_user.auth_user, permis_member)
                PermissionDao.user_add_perms(a_user.auth_user, [permis_member_new])
            
            a_user.save()
        """modify"""
        
        group.name = name
        group.save()
        
    
    """test"""
    @staticmethod
    def change_group_administrator(group_id, group_new_admin_name):
        
        group = GroupDao.get_group_by_id(group_id)  
        group_new_admin = UserDao.get_user_by_student_id(group_new_admin_name) 
        
        
        #if (not User.objects.filter(student_id=group_new_admin_name.student_id)):
        #    raise UserIDNotExisted(group_new_admin_name.student_id) 
        
        if ( group_new_admin.group is None ):
            raise UserNotInAnyGroup(group_new_admin.student_id)
       
        if ( not group_new_admin.group.name == group.name ):
            raise UserNotInThisGroup(group_new_admin.student_id)

        """modify"""
        group_old_admin = GroupDao.get_group_administrator(group_id)
        permis_admin = '.'.join([str(group.id), 'admin'])
        
        PermissionDao.user_remove_perm(group_old_admin.auth_user, permis_admin)
        PermissionDao.user_add_perm(group_new_admin.auth_user, permis_admin)
        """modify"""

        group.administrator = group_new_admin
        group.save()
        
        
        
    """test"""
    @staticmethod
    def get_group_by_name(group_name):
        
        group = Group.objects.filter(name = group_name)
        if ( not group ):
            raise GroupNotExisted(group_name)  
        else:
            group=group.get()
        
        return group
    
    @staticmethod
    def get_group_by_id(group_id):
        try:
            group_id = int(group_id)
        except Exception,e:
            raise e
            
        group = Group.objects.filter(id = group_id)
        if ( not group ):
            raise GroupNotExisted(group_id)  
        else:
            group=group.get()
        
        return group
    
    """test"""
    @staticmethod
    def join_group(group_id, user_id):
        
        group = GroupDao.get_group_by_id(group_id)
        user = UserDao.get_user_by_student_id(user_id)
        
        """
        if ( not Group.objects.filter(name = group.name) ):
            raise GroupNotExist(group.name)
        
        if (not User.objects.filter(student_id=user.student_id)):
            raise UserIDNotExisted(user.student_id)
        """
        
        if ( user.group is not None ):
            raise UserStillInAGroup(user.student_id)
        
      
        if ( group.users.all().count() >= SettingDao.get_setting('number_of_group_member') ):
            raise GroupMemberFull(group.name)
        
        """modify"""
        permis_member = '.'.join([str(group.id), 'member'])
        PermissionDao.user_add_perm(user.auth_user, permis_member)
        """modify"""
        
        user.group = group
        user.save()
    
    """test"""
    @staticmethod
    def quit_group(group_id,user_id):
        
        group = GroupDao.get_group_by_id(group_id)
        user = UserDao.get_user_by_student_id(user_id)
        
        """
        if ( not Group.objects.filter(name = group.name) ):
            raise GroupNotExisted(group.name)
        
        if ( not User.objects.filter(student_id=user.student_id) ):
            raise UserIDNotExisted(user.student_id)
        """
        
        if ( user.group == None ):
            raise UserNotInAnyGroup(user.student_id)
        
        if ( not user.group.name == group.name ):
            raise UserNotInThisGroup(user.student_id)

        if ( group.administrator.student_id == user.student_id and group.users.all().count()>1 ):
            raise UserIsAministrator(user.student_id)
        
        """modify"""
        permis_admin = '.'.join([str(group.id), 'admin'])
        permis_member = '.'.join([str(group.id), 'member'])
        
        print 'ok!!!!!!!!!'
        if ( group.administrator.student_id == user.student_id and group.users.all().count() == 1 ): 
            print 'ok5!!!!!!!!!'    
            group_admin = GroupDao.get_group_administrator(group_id)
            print 'ok6!!!!!!!!!'           
            print [permis_admin, permis_member]
            print user
            PermissionDao.user_remove_perms(user.auth_user, [permis_admin, permis_member])
            print 'ok7!!!!!!!!!'
            
        else:
            PermissionDao.user_remove_perm(user.auth_user, permis_member)
        """modify"""    
        print 'ok2!!!!!!!!!'
        user.group = None
        user.save()
        
        group.save()
        print 'ok3!!!!!!!!!'
        if ( group.users.all().count() == 0  ):
            GroupDao.delete_group(group_id)
        print 'ok4!!!!!!!!!'
    """test"""
    @staticmethod
    def get_group_administrator(group_id):
        
        group = GroupDao.get_group_by_id(group_id)
        return group.administrator

    @staticmethod
    def get_number_of_group():
        
        count = Group.objects.all().count() 
        return count
       
    @staticmethod
    def is_user_join_this_group(group_id,user_id):
        
        group = GroupDao.get_group_by_id(group_id)
        user = UserDao.get_user_by_student_id(user_id)
        
        if ( user.group == None ):
            return False
        
        if ( not user.group.id == group.id ):
            return False
        
        return True
    
    @staticmethod
    def get_group_list(start, limit):
        
        if ( start < 0 or start >= Group.objects.all().count() ):
            start = 0
            
        if ( limit < 0 ):
            limit = SettingDao.get_setting('group_number_per_page')
        
        output_group_list = Group.objects.all()[start:start+limit]
 
        return output_group_list
   
    @staticmethod
    def get_group_members_by_group_id(group_id):
        
        group = GroupDao.get_group_by_id(group_id)
        
        all_user = group.users.all()
        
        if ( all_user is None ):
            raise NoMemberInGroup(group_id)
        
        return all_user
    
#GroupDao.quit_group_by_id('G','002')        


"""
tmp_user = User()
new_group = Group(administrator=tmp_user, name='G2')
old_user = User.objects.get(student_id='003')

GroupDao.delete_group_by_name('G2')
"""

"""
tmp_user = User()

new_group = Group(administrator=tmp_user, name='G6')
GroupDao.create_group(new_group, '016')
"""
"""
group_list = GroupDao.get_group_list(100, 3)

for group in group_list:
    print group
"""
"""  
edit_group = Group.objects.get(name='G1')
GroupDao.edit_group_name(edit_group, 'GG1')
"""

"""
find_group = GroupDao.get_group_by_name('G2')
find_user = UserDao.get_user_by_student_id('005')
GroupDao.join_group(find_group, find_user)
"""


"""
edit_group = Group.objects.get(name='G1')
old_user = GroupDao.get_group_administrator(edit_group)
print old_user

new_user = UserDao.get_user_by_student_id('005')
GroupDao.change_group_administrator(edit_group, new_user)

new_admin = GroupDao.get_group_administrator(edit_group)
print new_admin
"""

"""
find_group = GroupDao.search_group_by_name('GG1')
print find_group
find_user = UserDao.search_user_by_student_id('010')
"""

"""
find_group = GroupDao.get_group_by_name('G2')
print find_group.users.all()
find_user = UserDao.get_user_by_student_id('005')
GroupDao.quit_group(find_group,find_user)
print find_group.users.all()
"""

"""
find_group = GroupDao.get_group_by_name('G1')
print find_group.users.all()
GroupDao.delete_group(find_group)
"""
"""
del_group = Group.objects.get(name='G1')
GroupDao.delete_group(del_group)
"""
"""
user = UserDao.get_user_by_student_id('005')
group =  Group(administrator=user, name='G5')

GroupDao.create_group(group,'005')
"""

"""
user = UserDao.get_user_by_student_id('001')
group =  Group(administrator=user, name='G1')
GroupDao.create_group(group,'001')

user = UserDao.get_user_by_student_id('002')
group =  Group(administrator=user, name='G2')
GroupDao.create_group(group,'002')

user = UserDao.get_user_by_student_id('003')
group =  Group(administrator=user, name='G3')
GroupDao.create_group(group,'003')
"""


"""
GroupDao.join_group_by_name('G1', '003')

GroupDao.join_group_by_name('G1', '005')
GroupDao.join_group_by_name('G1', '006')
"""

#GroupDao.quit_group_by_name('G3', '003')

"""
GroupDao.quit_group_by_name('G1', '004')
GroupDao.quit_group_by_name('G1', '005')
GroupDao.quit_group_by_name('G1', '006')
"""

"""
from pyExcelerator import *

w = Workbook()
ws = w.add_sheet('Mark')


ws.write(1, 1, 1)
ws.write(1, 2, 2)
ws.write(1, 3, 3)

w.save('mini.xls')


sheets = parse_xls('D:\WorkSpace_Python\sda\mini.xls')
print sheets['Mark']
"""